package com.moneywelcome.gateway.filters;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.moneywelcome.gateway.util.JWTHelper;
import com.moneywelcome.gateway.util.Result;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;

@Component
@Slf4j
public class AuthFilter implements GlobalFilter, Ordered {

    @Resource
    private JWTHelper jwtHelper;

    /**
     * 过滤逻辑
     *
     * @param exchange
     * @param chain
     * @return
     */
    @SneakyThrows
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //(1)放行登录请求
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        String path = request.getPath().value();
        log.info("path路径为:{}", path);
        if (path != null && (
                path.endsWith("/register") ||
                        path.endsWith("/Login")||
                        path.endsWith("/phoneLogin")||
                        path.startsWith("/sendcode/")||
                        path.endsWith("/updatePassword")
        )) {
            //放行
            return chain.filter(exchange);
        }

        //(2)其他请求，拦截获取jwt，判断jwt是否合法
        String jwt = request.getHeaders().getFirst("Authentication");
        if (StringUtils.isBlank(jwt)) {
            return getVoidMono(response);
        }
        try {
            Claims claims = jwtHelper.parseJWT(jwt);
            Object userId = claims.get("userId");
            if (userId != null) {
                int userIdInt = (int) userId;
                log.info("从jwt中获取到userId:{}" + userIdInt);
            }
            // 将userId放在header中向后传递
            request.mutate().header("userId", userId + "");
            return chain.filter(exchange);
        } catch (JwtException e) {
            log.error("网关：{}", e.getStackTrace());
            return getVoidMono(response);
        }


    }

    @Resource
    private ObjectMapper objectMapper;

    private Mono<Void> getVoidMono(ServerHttpResponse response) throws JsonProcessingException, UnsupportedEncodingException {
        Result result = new Result();
        result.setCode("NOT_AUTH");
        result.setMessage("请先登录");
        result.setSuccess(false);
        //解决中文乱码问题
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");

        //转换成json
        String jsonResult = objectMapper.writeValueAsString(result);

        DataBuffer dataBuffer = response.bufferFactory().wrap(jsonResult.getBytes("UTF-8"));

        return response.writeWith(Mono.just(dataBuffer));

    }


    //顺序
    @Override
    public int getOrder() {
        //在路由之前执行，比NettyRoutingFilter早
        return Ordered.LOWEST_PRECEDENCE - 10;
    }
}
